/**
 * Copyright (C) 2008 aileron.cc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cc.aileron.commons.accessor.factory;

import cc.aileron.commons.accessor.PojoAccessor;
import cc.aileron.commons.accessor.PojoAccessorConvertor;
import cc.aileron.commons.accessor.PojoAccessorConvertorFactory;
import cc.aileron.commons.accessor.PojoAccessorFactory;

import com.google.inject.Inject;
import com.google.inject.Injector;

/**
 * PojoAccessorFactory の guice container 対応版
 * @author Aileron
 *
 */
public class PojoAccessorFactoryGuice implements PojoAccessorFactory
{
    /*
     * (非 Javadoc)
     * @see cc.aileron.commons.accessor.PojoAccessorFactory#accessor(java.lang.Object)
     */
    public <T> PojoAccessor<T> accessor(T object)
    {
        return new PojoAccessorImpl<T>( this, instanceManager.newChainAccessor(instanceManager.newProperties(object)) );
    }

    /**
     * constractor set injector
     * @param injector
     */
    @Inject
    public PojoAccessorFactoryGuice(
            final Injector injector)
    {
        final PojoAccessorConvertorFactory factory = new PojoAccessorConvertorFactory()
        {
            /*
             * (非 Javadoc)
             * @see cc.aileron.commons.accessor.PojoAccessorConvertorFactory#getInstance(java.lang.String)
             */
            @SuppressWarnings("unchecked")
            public PojoAccessorConvertor<Object,Object> getInstance(
                    final String className)
            {
                try
                {
                    return injector.getInstance(Class.forName(className).asSubclass(PojoAccessorConvertor.class));
                }
                catch (ClassNotFoundException e)
                {
                    throw new RuntimeException(e);
                }
            }

            /*
             * (非 Javadoc)
             * @see cc.aileron.commons.accessor.PojoAccessorConvertorFactory#getInstance(java.lang.Class)
             */
            @SuppressWarnings("unchecked")
            public PojoAccessorConvertor<Object, Object> getInstance(
                    Class<? extends PojoAccessorConvertor<?, ?>> targetClass)
            {
                return (PojoAccessorConvertor<Object, Object>) injector.getInstance(targetClass);
            }   
        };
        this.instanceManager = new PojoAccessorInstanceManagerImpl()
        {
            @Override
            public PojoAccessorConvertorFactory getConvertorFactory()
            {
                return factory;
            }
        };
    }
    
    /**
     * instance-manager
     */
    private final PojoAccessorInstanceManager instanceManager;

    /*
     * (非 Javadoc)
     * @see cc.aileron.commons.accessor.PojoAccessorFactory#getInstanceManager()
     */
    public PojoAccessorInstanceManager getInstanceManager()
    {
        return instanceManager;
    }
}
